package cn.s1995.sloth.bizs.service.impl;

import cn.s1995.sloth.bizs.constant.CacheNames;
import cn.s1995.sloth.common.core.constant.enums.hint.Hint;
import cn.s1995.sloth.bizs.entity.UserAddress;
import cn.s1995.sloth.bizs.exception.BizException;
import cn.s1995.sloth.bizs.mapper.UserAddressMapper;
import cn.s1995.sloth.bizs.service.UserAddressService;
import cn.s1995.sloth.bizs.service.common.CacheService;
import cn.s1995.sloth.common.core.util.SpringContextHolder;
import cn.s1995.sloth.common.security.util.SecurityUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * 用户收货地址
 *
 * @author Lex
 * @date 2023-12-26 10:36:43
 */
@Service
public class UserAddressServiceImpl extends ServiceImpl<UserAddressMapper, UserAddress> implements UserAddressService {

    @Resource
    private CacheService cacheService;

    @Override
    public UserAddress getDefaultAddress(Long userId) {
        return getOne(
                Wrappers.lambdaQuery(UserAddress.class)
                        .eq(UserAddress::getUid, userId)
                        .eq(UserAddress::getIsDefaulted, Boolean.TRUE),
                Boolean.FALSE
        );
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateDefaultUserAddr(Long addrId, Long userId) {
        update(
                Wrappers.lambdaUpdate(UserAddress.class)
                        .set(UserAddress::getIsDefaulted, Boolean.FALSE)
                        .eq(UserAddress::getUid, userId)
        );

        update(
                Wrappers.lambdaUpdate(UserAddress.class)
                        .set(UserAddress::getIsDefaulted, Boolean.TRUE)
                        .eq(UserAddress::getUid, userId)
                        .eq(UserAddress::getId, addrId)
        );
    }

    @Override
    @CacheEvict(cacheNames = CacheNames.userAddress, key = "#userId+':'+#addrId")
    public void removeCacheUserAddressByUserId(Long addrId, Long userId) {

    }

    @Override
    @Cacheable(cacheNames = CacheNames.userAddress, key = "#userId+':'+#addrId")
    public UserAddress getUserAddrByUserId(Long addrId, Long userId) {
        // 没有地址id，获取默认地址
        if (Objects.isNull(addrId) || addrId == 0) {
            return getDefaultAddress(userId);
        }
        return getOne(
                Wrappers.lambdaQuery(UserAddress.class)
                        .eq(UserAddress::getUid, userId)
                        .eq(UserAddress::getId, addrId),
                Boolean.FALSE
        );
    }

    public static void main(String[] args) {
        Long a = null;
        System.out.println(a == 0);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAddress(UserAddress req) {
        Long userId = SecurityUtils.getUser().getId();
        req.setUid(userId);

        if (Objects.isNull(req.getIsDefaulted())) {
            long count = this.count(
                    Wrappers.lambdaQuery(UserAddress.class)
                            .eq(UserAddress::getUid, userId)
            );
            long shoppingAddressMaxLimit = cacheService.getShoppingAddressMaxLimit();
            if (count >= shoppingAddressMaxLimit) {
                throw new BizException(Hint.APP_SHOPPING_ADDRESS_MAX_LIMIT, shoppingAddressMaxLimit);
            }
            req.setIsDefaulted(count == 0);
        }

        save(req);

        if (req.getIsDefaulted()) {
            // 清除默认地址
            this.update(
                    Wrappers.lambdaUpdate(UserAddress.class)
                            .set(UserAddress::getIsDefaulted, Boolean.FALSE)
                            .eq(UserAddress::getUid, userId)
            );
            // 清除默认地址缓存
            SpringContextHolder.getBean(UserAddressService.class).removeCacheUserAddressByUserId(0L, userId);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAddress(UserAddress req) {
        Long userId = SecurityUtils.getUser().getId();
        req.setUid(userId);

        UserAddress userAddress = this.getUserAddrByUserId(req.getId(), userId);
        if (Objects.isNull(userAddress)) {
            throw new BizException(Hint.APP_USER_ADDRESS_NOT_EXIST);
        }
        if (req.getIsDefaulted()) {
            // 清除默认地址
            this.update(
                    Wrappers.lambdaUpdate(UserAddress.class)
                            .set(UserAddress::getIsDefaulted, Boolean.FALSE)
                            .eq(UserAddress::getUid, userId)
            );
        }

        this.updateById(req);

        // 清除当前地址缓存
        SpringContextHolder.getBean(UserAddressService.class).removeCacheUserAddressByUserId(req.getId(), userId);
        // 清除默认地址缓存
        SpringContextHolder.getBean(UserAddressService.class).removeCacheUserAddressByUserId(0L, userId);

    }
}
